import { AppData } from "./app";
import { Token } from "./token";

export const request = (
  url: string,
  data: AnyObject,
  success: (e: any) => void,
  fail: (e: Error & { errorCode?: number; errorMsg?: string }) => void,
  options?: { header?: AnyObject; method?: "GET" | "POST" }
) => {
  return uni.request({
    url,
    data,
    ...options,
    success: resp => getResponseData(resp, success, fail),
    fail: error => {
      console.error(url, error);
      fail(new Error(error.errMsg));
    },
  });
};

export const getRequestHeader = () => {
  return { auth: Token.auth, cpl: Token.cpl };
};
export const getResponseData = (
  resp: any,
  success: (e: any) => void,
  fail: (error: any) => void
) => {
  const data = (
    Object.prototype.toString.call(resp.data) === "[object String]"
      ? JSON.parse((resp.data as string).replace(/\ufeff/g, ""))
      : resp.data
  ) as Response;
  // console.log(data);
  data.errorCode === 1
    ? success(data.result)
    : fail(Object.assign(new Error(data.errorMsg), data));
};

const requestR = <T>(
  url: string,
  data: AnyObject,
  options?: { method?: "GET" | "POST" },
  requestTask?: { abort: () => void }
) => {
  return new Promise<T>((resolve, reject) => {
    const task = request(
      `${AppData.domain}/api${url}`,
      data,
      resp => {
        console.log(url, resp);
        resolve(resp);
      },
      reject,
      { ...options, header: getRequestHeader() }
    );
    if (requestTask) requestTask.abort = () => task.abort();
  });
};

export class Http {
  static get<T>(
    url: string,
    data?: AnyObject,
    requestTask?: { abort: () => void }
  ) {
    return requestR<T>(url, data || {}, {}, requestTask);
  }

  static post<T>(
    url: string,
    data?: AnyObject,
    requestTask?: { abort: () => void }
  ) {
    return requestR<T>(url, data || {}, { method: "POST" }, requestTask);
  }
}

interface Response {
  errorCode: number | 1 | 501;
  errorMsg: string;
  result: any;
}
